#pragma once

#include "Serializable.h"
#include "PeopleData.h"
#include "PeopleHistory.h"
#include "StlStringAndStreams.h"

#ifndef DARIO
struct Contract
{
	explicit Contract(unsigned int i_salary = 0, unsigned int i_years = 0)
			: m_salary(i_salary),
			  m_years(i_years)
	{}

	unsigned int m_salary;
	unsigned int m_years;

	static const int SELL_FACTOR = 2;
	static const int BUY_FACTOR = 20;

	void Serialize(ZStream& o_stream) const;
	void Deserialize(ZStream& i_stream);

	void SeasonUpdate()
	{
		--m_years;
	}

	int BuyValue() const
	{
		return m_salary * BUY_FACTOR;
	}

	int SellValue() const
	{
		return m_salary * SELL_FACTOR * m_years;
	}
};
#endif

class People : public Serializable
{
public:
	People(){}
	People(const STL::string& i_name, const int i_id, const bool i_isPlayer);
	void Generate(const STL::string& i_name, const int i_id, const bool i_isPlayer);

	const PeopleHistory& GetHistory() const;
	
	const STL::string& GetName() const;
	int GetId() const;

	// People & People has a salary, but only player has Buy&Sell Values...
	int GetSalary() const;
	int BuyValue() const;
	int SellValue() const;

	void SetTeamID(const int i_teamID);
	const int GetTeamID() const;
	bool IsBusy() const;

	const PeopleSkills& GetSkills() const;

	void PlayerPostMatch(
		const int i_playedRole, const int i_formation, const int i_scoredGoal, 
		const int i_evaluation, const bool i_isMoM, const int i_card, const bool i_isTired, 
		People * const* const i_trainerRoles, int* o_daysPenalty = 0, int* o_daysInjury = 0);
	
	void TrainerPostMatch(const int i_trainedRoles);

	// delegation on history
	bool IsRetired() const;
	bool IsPlayer() const;
	bool IsTrainer() const;
	int GetStatus() const;

	int GetRetirePercent() const;

#ifndef DARIO
	// set contract
	void SetContract(const unsigned int i_salary, const unsigned int i_years);
	const Contract* const GetContract() const;
	bool HasContract() const;
#endif

	const unsigned int CalculateExpectedSalary() const;

	const PlayerAvailability& GetAvailability() const;
	PlayerAvailability& GetAvailability();

	const int InjuryTest(const bool i_isTired);

	bool SeasonUpdate();

	virtual	ZStream& Serialize(ZStream& o_stream) const;
	virtual ZStream& Deserialize(ZStream& i_stream);

	static const PeopleParams& GetParams();
	static const int NUM_HOF_PEOPLE = 200;

private:
	//copy disabled
	People(const People&); 
	People& operator=(const People&);

	DARIONLY(void CalculateSalary());
	void EndSeason();
	bool CheckRetirement() const;
	bool BecomeTrainer();

	void PostMatchPlayerUpdateSkills(const int i_playedRole, const int i_formation, People * const* const i_trainerRoles);
	void PostMatchTrainerUpdateSkills(const int i_trainedRoles);
	void PostMatchPlayerUpdatePhysicsSkills(const int i_playedRole);
	void PostMatchPlayerUpdatePlayerSkill(int& o_skill, const int i_tSkill, const int i_playedRolePercent, const bool i_play);
	void PostMatchPlayerUpdateTrainerSkill(int& o_skill, const int i_playedRolePercent, const bool i_play);
	void PostMatchPlayerUpdateStamina();
	void TryUpSkill(int& o_skill, const int i_diceRoll);

	friend class PeopleManager;

	static const int MAX_DAY_OFF = 33;
	static PeopleParams s_params;

	PeopleHistory m_history;
	
	PeopleSkills m_skill;

	PlayerAvailability m_availability;
	
	STL::string m_name;
	int m_id;
	int m_teamID;
	DARIONLY(int m_salary);
	NOTDARIONLY(Contract m_contract);
};

#include "People.inl"
